//*****************************************************************************
//
// startup.c - Boot code for Stellaris.
//
// Copyright (c) 2005-2007 Luminary Micro, Inc.  All rights reserved.
// 
// Software License Agreement
// 
// Luminary Micro, Inc. (LMI) is supplying this software for use solely and
// exclusively on LMI's microcontroller products.
// 
// The software is owned by LMI and/or its suppliers, and is protected under
// applicable copyright laws.  All rights are reserved.  Any use in violation
// of the foregoing restrictions may subject the user to criminal sanctions
// under applicable laws, as well as to civil liability for the breach of the
// terms and conditions of this license.
// 
// THIS SOFTWARE IS PROVIDED "AS IS".  NO WARRANTIES, WHETHER EXPRESS, IMPLIED
// OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
// LMI SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
// CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
// 
// This is part of revision 1392 of the Stellaris Peripheral Driver Library.
//
//*****************************************************************************

//*****************************************************************************
//
// Forward declaration of the default fault handlers.
//
//*****************************************************************************

#include <stdio.h>
#include "hw_types.h"
#include "hw_memmap.h"
#include "hw_watchdog.h"
#include "watchdog.h"

void ResetISR(void);
static void NmiSR(void);
static void FaultISR(void);
static void IntDefaultHandler(void);
static void IntEmptyHandler(void);
static void WatchdogIntHandler(void);

//*****************************************************************************
//
// The entry point for the application.
//
//*****************************************************************************
extern int main(void);

extern void xPortPendSVHandler(void);
extern void xPortSysTickHandler(void);
extern void vPortSVCHandler(void);
extern void Timer0IntHandler(void);
extern void ETH0IntHandler(void);

//extern void UARTStdioIntHandler(void);

//*****************************************************************************
//
// External declarations for the interrupt handlers used by the application.
//
//*****************************************************************************
extern void TouchScreenIntHandler(void);
extern void SoundIntHandler(void);

//*****************************************************************************
//
// Reserve space for the system stack.
//
//*****************************************************************************
#ifndef STACK_SIZE
#define STACK_SIZE                              120
#endif
static unsigned long pulStack[STACK_SIZE];

//*****************************************************************************
//
// The minimal vector table for a Cortex M3.  Note that the proper constructs
// must be placed on this to ensure that it ends up at physical address
// 0x0000.0000.
//
//*****************************************************************************
__attribute__ ((section(".isr_vector")))
void (* const g_pfnVectors[])(void) =
{ (void(*)(void)) ((unsigned long) pulStack + sizeof(pulStack)),
// The initial stack pointer
		ResetISR, // The reset handler
		NmiSR, // The NMI handler
		FaultISR, // The hard fault handler
		IntDefaultHandler, // The MPU fault handler
		IntDefaultHandler, // The bus fault handler
		IntDefaultHandler, // The usage fault handler
		0, // Reserved
		0, // Reserved
		0, // Reserved
		0, // Reserved
		vPortSVCHandler, // SVCall handler
		IntDefaultHandler, // Debug monitor handler
		0, // Reserved
		xPortPendSVHandler, // The PendSV handler
		xPortSysTickHandler, // The SysTick handler
		IntDefaultHandler, // GPIO Port A
		IntDefaultHandler, // GPIO Port B
		IntDefaultHandler, // GPIO Port C
		IntDefaultHandler, // GPIO Port D
		IntDefaultHandler, // GPIO Port E
		IntEmptyHandler, // UART0 Rx and Tx
		IntDefaultHandler, // UART1 Rx and Tx
		IntDefaultHandler, // SSI0 Rx and Tx
		IntDefaultHandler, // I2C0 Master and Slave
		IntDefaultHandler, // PWM Fault
		IntDefaultHandler, // PWM Generator 0
		IntDefaultHandler, // PWM Generator 1
		IntDefaultHandler, // PWM Generator 2
		IntDefaultHandler, // Quadrature Encoder 0
		IntDefaultHandler, // ADC Sequence 0
		IntDefaultHandler, // ADC Sequence 1
		IntDefaultHandler, // ADC Sequence 2
		TouchScreenIntHandler, // ADC Sequence 3
		WatchdogIntHandler, // Watchdog timer
		Timer0IntHandler, // Timer 0 subtimer A
		IntDefaultHandler, // Timer 0 subtimer B
		IntDefaultHandler, // Timer 1 subtimer A
		IntDefaultHandler, // Timer 1 subtimer B
		IntDefaultHandler, // Timer 2 subtimer A
		IntDefaultHandler, // Timer 2 subtimer B
		IntDefaultHandler, // Analog Comparator 0
		IntDefaultHandler, // Analog Comparator 1
		IntDefaultHandler, // Analog Comparator 2
		IntDefaultHandler, // System Control (PLL, OSC, BO)
		IntDefaultHandler, // FLASH Control
		IntDefaultHandler, // GPIO Port F
		IntDefaultHandler, // GPIO Port G
		IntDefaultHandler, // GPIO Port H
		IntDefaultHandler, // UART2 Rx and Tx
		IntDefaultHandler, // SSI1 Rx and Tx
		IntDefaultHandler, // Timer 3 subtimer A
		IntDefaultHandler, // Timer 3 subtimer B
		IntDefaultHandler, // I2C1 Master and Slave
		IntDefaultHandler, // Quadrature Encoder 1
		IntDefaultHandler, // CAN0
		IntDefaultHandler, // CAN1
		IntDefaultHandler, // CAN2
		ETH0IntHandler, // Ethernet
		IntDefaultHandler, // Hibernate
		IntDefaultHandler, // USB0
		IntDefaultHandler, // PWM Generator 3
		IntDefaultHandler, // uDMA Software Transfer
		IntDefaultHandler, // uDMA Error
		IntDefaultHandler, // ADC1 Sequence 0
		IntDefaultHandler, // ADC1 Sequence 1
		IntDefaultHandler, // ADC1 Sequence 2
		IntDefaultHandler, // ADC1 Sequence 3
		SoundIntHandler, // I2S0
		IntDefaultHandler, // External Bus Interface 0
		IntDefaultHandler // GPIO Port J
		};

//*****************************************************************************
//
// The following are constructs created by the linker, indicating where the
// the "data" and "bss" segments reside in memory.  The initializers for the
// for the "data" segment resides immediately following the "text" segment.
//
//*****************************************************************************
//
// The following are constructs created by the linker, indicating where the
// the "data" and "bss" segments reside in memory.
//
//*****************************************************************************
extern unsigned long _flash_data;
extern unsigned long _data;
extern unsigned long _edata;
extern unsigned long _bss;
extern unsigned long _ebss;

//*****************************************************************************
//
// This is the code that gets called when the processor first starts execution
// following a reset event. Only the absolutely necessary set is performed,
// after which the application supplied entry() routine is called. Any fancy
// actions (such as making decisions based on the reset cause register, and
// resetting the bits in that register) are left solely in the hands of the
// application.
//
//*****************************************************************************
void ResetISR(void)
{
	unsigned long *pulSrc, *pulDest;
	//
	// Fill the stack with a known value.
	//
	for (pulDest = pulStack; pulDest < pulStack + STACK_SIZE;)
	{
		*pulDest++ = 0xABCD;
	}
	//
	// Copy the data segment initializers from flash to SRAM.
	//
	pulSrc = &_flash_data;
	for (pulDest = &_data; pulDest < &_edata;)
	{
		*pulDest++ = *pulSrc++;
	}
	//
	// Zero fill the bss segment.
	//
	for (pulDest = &_bss; pulDest < &_ebss;)
	{
		*pulDest++ = 0;
	}
	//
	//Call the global objets constructors
	//
	//ma  __libc_init_array();
	//
	// Call the application's entry point.
	//
	main();
}

//*****************************************************************************
//
// This is the code that gets called when the processor receives a NMI.  This
// simply enters an infinite loop, preserving the system state for examination
// by a debugger.
//
//*****************************************************************************
static void NmiSR(void)
{
	//
	// Enter an infinite loop.
	//
	printf("FATAL ERROR: NmiSR()");
	while (1)
	{
	}
}

//*****************************************************************************
//
// This is the code that gets called when the processor receives a fault
// interrupt.  This simply enters an infinite loop, preserving the system state
// for examination by a debugger.
//
//*****************************************************************************
static void FaultISR(void)
{
	//
	// Enter an infinite loop.
	//
	printf("FATAL ERROR: FaultISR()");
	while (1)
	{
	}
}

//*****************************************************************************
//
// This is the code that gets called when the processor receives an unexpected
// interrupt.  This simply enters an infinite loop, preserving the system state
// for examination by a debugger.
//
//*****************************************************************************
static void IntDefaultHandler(void)
{
	//
	// Go into an infinite loop.
	//
	printf("FATAL ERROR: IntDefaultHandler()");
	while (1)
	{
	}
}

static void IntEmptyHandler(void)
{

}

//*****************************************************************************
//
// The interrupt handler for the watchdog.  This feeds the dog (so that the
// processor does not get reset) and winks the LED connected to GPIO B3.
//
//*****************************************************************************
static void WatchdogIntHandler(void)
{
	//
	// Clear the watchdog interrupt.
	//
	WatchdogIntClear(WATCHDOG0_BASE);
}
